package com.mytijian.openapi.adapter.dianping.client;

import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

import com.alibaba.fastjson.JSON;
import com.dianping.utils.DzOpenParamConvertUtil;
import com.dianping.utils.DzopenSignUtil;
import com.mysql.fabric.xmlrpc.base.Array;
import com.mytijian.openapi.adapter.dianping.exceptions.DzopenErrorInfo;
import com.mytijian.openapi.adapter.dianping.exceptions.DzopenException;
import com.mytijian.openapi.adapter.dianping.result.DzResult;
import com.mytijian.openapi.core.exception.OpenClientNetException;

public class DzopenUtils {

    private static Logger logger = LoggerFactory.getLogger(DzopenUtils.class);

    public static DzResult<?> sendRequest(String url, String signKey, Object t) {

        Map<String, String> map = DzOpenParamConvertUtil.objectToMap(t);

        try {
            String sign = DzopenSignUtil.signTopRequest(map, signKey);
            map.put("sign", sign);
        } catch (NoSuchAlgorithmException | IOException e) {

        }
        String postStr = DzOpenParamConvertUtil.mapToString(map);

        System.out.println("发送请求：" + postStr);

        String resultString = doPost(url, postStr);
        System.out.println("请求结果：" + resultString);
        return JSON.parseObject(resultString, DzResult.class);
    }


    public static <T> T sendRequest(String url, String signKey, Object t, Class<T> resultClass) {

        Map<String, String> map = DzOpenParamConvertUtil.objectToMap(t);

        try {
            String sign = DzopenSignUtil.signTopRequest(map, signKey);
            map.put("sign", sign);
        } catch (NoSuchAlgorithmException | IOException e) {

        }
        String postStr = DzOpenParamConvertUtil.mapToString(map);

        System.out.println("发送请求：" + postStr);

        String resultString = doPost(url, postStr);
        System.out.println("请求结果：" + resultString);
        return JSON.parseObject(resultString, resultClass);
    }

    /**
     * 移除不参与签名的字段
     *
     * @param signMap
     */
    public static Map<String, String> buildSignMap(Map<String, String> map, List<String> signFields) {
        Map<String, String> signMap = new HashMap<>();
        for (String key : signFields) {
            String value = map.get(key);
            signMap.put(key, value);
        }
        return signMap;
    }

    public static void verifySign(Map<String, String> requestMap, String signKey, List<String> signFields) {


        String sign = requestMap.get("sign");

        Map<String, String> signMap = buildSignMap(requestMap, signFields);

        try {
            String localSign = DzopenSignUtil.signTopRequest(signMap, signKey);
            System.out.println("local-sign: " + localSign);
            if (!sign.equals(localSign)) {
                System.out.println("签名不匹配");
                throw new DzopenException(DzopenErrorInfo.SIGN_ERROR);
            }
        } catch (NoSuchAlgorithmException | IOException e) {
            logger.error("美团点评 接口验签失败 ", e);
        }
    }

    public static String doPost(String url, String postStr) {
        logger.info("[DzopenUtil] 调用 url :{} \r\nPost-Data:{}", url, postStr);
        CloseableHttpClient client = getHttpClient();
        HttpPost request = new HttpPost(url);
        request.setHeader("Content-Type", "application/x-www-form-urlencoded");
        request.setHeader("charset", "UTF-8");

        try {
            if (!StringUtils.isEmpty(postStr)) {
                StringEntity entity = new StringEntity(postStr, "UTF-8");
                request.setEntity(entity);
            }
            HttpResponse response = client.execute(request);
            String result = responseToString(response);
            return result;
        } catch (Exception e) {
            logger.error("[open-client] [网络调用错误] 异常:{}", e);
            throw new OpenClientNetException(e);
        } finally {
            try {
                client.close();
            } catch (IOException e) {
                logger.error("[open-client] [httpclient 关闭异常] 异常:{}", e);
            }
        }
    }

    private static CloseableHttpClient getHttpClient() {
        HttpClientBuilder builder = HttpClientBuilder.create();
        CloseableHttpClient client = builder.build();
        return client;
    }

    private static String responseToString(HttpResponse response) throws IOException {
        return EntityUtils.toString(response.getEntity(), "UTF-8");
    }
}
